<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <!--引入cdn-->
</head>
<body>
    <div id="app">
        <h1 id="hh">{{msg}}</h1>
        <child></child>
    </div>
</body>
<script>
    //组件相互嵌套，钩子函數的执行顺序是什么?
    Vue.component('child',{
        template:'<h1>子组件</h1>',
        beforeCreate () {
            console.log('子组件的beforeCreate');
        },
        created () {
            console.log('子组件的created');
        },
        beforeMount () {
            console.log('子组件的beforeMount');
        },
        mounted () {
            console.log('子组件的mounted');
        },
        beforeUpdate () {
            console.log('子组件的beforeUpdate');
        },
        updated () {
            console.log('子组件的updated');
        },
        beforeDestroy () {
            console.log('子组件的beforeDestroy');
        },
        destroyed () {
            console.log('子组件的destroyed');
        }
    })
    const vm = new Vue({
        el:'#app',
        data:{
            msg:'钩子函数'
        },
        beforeCreate () {//创建之前
            // 只执行一次
            // 在这个钩子函数中是不允许修data中的属性的
            //$el就是虚拟dom

/*          console.group('beforeCreate')
            console.groupEnd()
            他们是一个组合，可以将打印的东西分为一组 */

            console.group('beforeCreate')
            console.log('虚拟dom $el===',this.$el); //underfined
            console.log('数据 $data===',this.$data);//underfined
            console.log('h1===',document.getElementById("hh").innerText);//h1=== {{msg}}
            console.groupEnd()
        },
        created () { //创建之后
            // 只执行一次
            //在这里可以获取data,并且事件监听也添加上了，数据已经被劫持，观察者就绪，在这个钩子函数中可以修改data
            console.group('created')
            console.log('虚拟dom $el===',this.$el); //underfined
            console.log('数据 $data===',this.$data); //可以获取data
            console.log('h1===',document.getElementById("hh").innerText); //h1=== {{msg}}
            console.groupEnd()
        },
        beforeMount () { //挂载之前 
            // 只执行一次
            // vue创建的虚拟dom，转换成真实dom的一个过程叫做挂载
            //虚拟dom已经被创建了，但是数据还没有更新，插值还没有被解析,也没有替换页面的真实dom
            //虚拟dom:通过js模拟真实dom的嵌套，创建出来的结构，就是虚拟dom。虚拟dom是在内存中的,页面是看不见的，只有添加到页面上才能看见
//创建虚拟dom无非就是用js学过的document.createEment () 

//为什么要使用虚拟dom?使用虚拟dom,可以在内存中更新结构,而不是操作真实dom一个一个更新,最大的好处是可以提高页面渲染的性能，结合diff算法让页面进行高效更新
            console.group('beforeMount')
            console.log('虚拟dom $el===',this.$el); //可以打印虚拟dom
            console.log('数据 $data===',this.$data); //可以获取data
            console.log('h1===',document.getElementById("hh").innerText); //h1=== {{msg}}
            console.groupEnd()
        },
        mounted () { //挂在之后
            // 只执行一次
            // 用虚拟dom直接替换掉了页面上的div#app所有的内容
            //一切已经准备就绪，虚拟dom已经更新并且替换掉了真实dom中的内容,完成了虚拟dom到真实dom的过程
            //这是个万金油钩子使用频率最高的钩子函数
            console.group('mounted')
            console.log('虚拟dom $el===',this.$el); //可以打印虚拟dom
            console.log('数据 $data===',this.$data); //可以获取data
            console.log('h1===',document.getElementById("hh").innerText); //h1=== 钩子函数
            console.groupEnd()
        },
        beforeUpdate () { //更新之前
            // 可能执行多次
            // data更新之后才能触发
            console.group(' beforeUpdate')
            console.log('虚拟dom $el===',this.$el); //可以打印虚拟dom
            console.log('数据 $data===',this.$data); //可以获取data
            console.log('h1===',document.getElementById("hh").innerText); //h1=== 钩子函数
            console.groupEnd()
        },
        updated () { //更新之后
            // 可能执行多次
            // data更新之后才能触发
            console.group('updated')
            console.log('虚拟dom $el===',this.$el); //可以打印虚拟dom
            console.log('数据 $data===',this.$data); //可以获取data
            console.log('h1===',document.getElementById("hh").innerText); //h1=== 钩子函数
            console.groupEnd()
        },
        beforeDestroy () { //销毁之前
             // 只执行一次
            //动态组件切换，路由组件切换都会触发这两个钩子函数
//卸载持续性的事件监听比如video audio 中监听进度条的事件
//卸载定时器
            console.log('卸载之前');
        },
        destroyed () { //销毁之后
             // 只执行一次
            console.log('卸载之后');
            
        }
    })
</script>
</html>